namespace WeatherSystem.API.Exceptions
{
    /// <summary>
    /// Base weather system exception
    /// </summary>
    public abstract class WeatherSystemException : Exception
    {
        public string ErrorCode { get; }
        public int HttpStatusCode { get; }

        protected WeatherSystemException(string errorCode, string message, int httpStatusCode = 500) 
            : base(message)
        {
            ErrorCode = errorCode;
            HttpStatusCode = httpStatusCode;
        }

        protected WeatherSystemException(string errorCode, string message, Exception innerException, int httpStatusCode = 500) 
            : base(message, innerException)
        {
            ErrorCode = errorCode;
            HttpStatusCode = httpStatusCode;
        }
    }

    /// <summary>
    /// Weather data not found exception
    /// </summary>
    public class WeatherDataNotFoundException : WeatherSystemException
    {
        public WeatherDataNotFoundException(Guid id) 
            : base("WEATHER_DATA_NOT_FOUND", $"未找到ID为 {id} 的天气数据", 404)
        {
        }

        public WeatherDataNotFoundException(Guid cityId, DateTime date) 
            : base("WEATHER_DATA_NOT_FOUND", $"未找到城市 {cityId} 在 {date:yyyy-MM-dd} 的天气数据", 404)
        {
        }
    }

    /// <summary>
    /// City not found exception
    /// </summary>
    public class CityNotFoundException : WeatherSystemException
    {
        public CityNotFoundException(Guid cityId) 
            : base("CITY_NOT_FOUND", $"未找到ID为 {cityId} 的城市", 404)
        {
        }

        public CityNotFoundException(string cityName) 
            : base("CITY_NOT_FOUND", $"未找到名称为 {cityName} 的城市", 404)
        {
        }
    }

    /// <summary>
    /// Data collection exception
    /// </summary>
    public class DataCollectionException : WeatherSystemException
    {
        public DataCollectionException(string message) 
            : base("DATA_COLLECTION_FAILED", message, 500)
        {
        }

        public DataCollectionException(string message, Exception innerException) 
            : base("DATA_COLLECTION_FAILED", message, innerException, 500)
        {
        }
    }

    /// <summary>
    /// Validation exception
    /// </summary>
    public class WeatherSystemValidationException : WeatherSystemException
    {
        public Dictionary<string, string[]> ValidationErrors { get; }

        public WeatherSystemValidationException(Dictionary<string, string[]> validationErrors) 
            : base("VALIDATION_FAILED", "数据验证失败", 400)
        {
            ValidationErrors = validationErrors;
        }

        public WeatherSystemValidationException(string field, string error) 
            : base("VALIDATION_FAILED", "数据验证失败", 400)
        {
            ValidationErrors = new Dictionary<string, string[]>
            {
                [field] = new[] { error }
            };
        }
    }

    /// <summary>
    /// External API exception
    /// </summary>
    public class ExternalApiException : WeatherSystemException
    {
        public string? ApiName { get; }

        public ExternalApiException(string apiName, string message) 
            : base("EXTERNAL_API_ERROR", $"{apiName} API 调用失败: {message}", 502)
        {
            ApiName = apiName;
        }

        public ExternalApiException(string apiName, string message, Exception innerException) 
            : base("EXTERNAL_API_ERROR", $"{apiName} API 调用失败: {message}", innerException, 502)
        {
            ApiName = apiName;
        }
    }

    /// <summary>
    /// Authentication exception
    /// </summary>
    public class WeatherSystemAuthenticationException : WeatherSystemException
    {
        public WeatherSystemAuthenticationException(string message) 
            : base("AUTHENTICATION_FAILED", message, 401)
        {
        }
    }

    /// <summary>
    /// Authorization exception
    /// </summary>
    public class WeatherSystemAuthorizationException : WeatherSystemException
    {
        public WeatherSystemAuthorizationException(string message) 
            : base("AUTHORIZATION_FAILED", message, 403)
        {
        }
    }

    /// <summary>
    /// Rate limit exception
    /// </summary>
    public class RateLimitExceededException : WeatherSystemException
    {
        public RateLimitExceededException(string message) 
            : base("RATE_LIMIT_EXCEEDED", message, 429)
        {
        }
    }

    /// <summary>
    /// Concurrent operation exception
    /// </summary>
    public class ConcurrentOperationException : WeatherSystemException
    {
        public ConcurrentOperationException(string resourceId) 
            : base("CONCURRENT_OPERATION", $"资源 {resourceId} 正在被其他操作修改", 409)
        {
        }
    }
}